#ifndef _NNSLITE_GLOBAL_H_
#define _NNSLITE_GLOBAL_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <assert.h>

/* Data type definitions */
typedef unsigned char  u8;
typedef unsigned short u16;
typedef unsigned int   u32;
typedef unsigned long long u64;
typedef char   s8;
typedef short  s16;
typedef int    s32;
typedef long long s64;
typedef float  f32;
typedef double f64;

#define U8_MAX_VAL   0xFE
#define U8_NULL U8_  MAX_VAL
#define U16_MAX_VAL  0xFFFE
#define U16_NULL     U16_MAX_VAL
#define U32_MAX_VAL  0xFFFFFFFE
#define U32_NULL     U32_MAX_VAL
#define U64_MAX_VAL  (U64)(-1)
#define U64_NULL     U64_MAX_VAL
#define F64_MAX_VAL  DBL_MAX

/* Fixed memory and storage size definitions */
#define NNSLITE_MAX_NAMELEN 64
#define NNSLITE_CELL_CAPACITY (16*1024)
#define NNSLITE_CHUNK_SIZE  (4*NNSLITE_CELL_CAPACITY)
#define NNSLITE_MAX_FILE_SECTION   32
#define NNSLITE_MAX_NUM_DATAPAGE   128

#define NNSLITE_MTREE_MAX_CHILD 4
#define NNSLITE_MTREE_MAX_DEPTH 6



/* Return Code */
typedef s32 NNSLITE_RET;
#define NNSLITE_RET_OK      0
#define NNSLITE_RET_ERR     -1
#define NNSLITE_RET_ERR_ALLOCATE_MEM         -2
#define NNSLITE_RET_ERR_INDEX_OUTOFBOUND     -3
#define NNSLITE_RET_ERR_FILE_CANNOT_OPEN     -100

#define NNSLITE_RET_ERR_DATAPAGE             -1001
#define NNSLITE_RET_ERR_DATAPAGE_OUTOFLIMIT  -1002
#define NNSLITE_RET_ERR_NO_MORE_SPACE        -1003

#define NNSLITE_RET_ERR_FILE_SECTION_OUTOFLIMIT -1031

#define NNSLITE_RET_TRUE    1
#define NNSLITE_RET_FALSE   0




#ifndef TRUE
#define TRUE  1
#define FALSE 0
#endif

#ifndef MAX
#define MAX(a,b) ((a)>=(b)?(a):(b))
#endif

#ifndef MIN
#define MIN(a,b) ((a)>=(b)?(b):(a))
#endif

/* Macros */
#define NNSLITE_FAILED(ret) (ret<0)

#define NNSLITE_ON_FAILED_RETURN(ret)  \
	{									\
		if (NNSLITE_FAILED(ret))		\
		{	assert(FALSE);				\
			return ret;					\
		}								\
	};


/** nnsliteObject */
struct nnsliteObject
{
	void* data;
	u32 size;
	u64 id;
};


typedef struct nnsliteObject nnsliteObject;

/** Similarity Distance Function Definition */
typedef f64 (*nnsliteDistFunc)(const nnsliteObject* object1, const nnsliteObject* object2);

#define NNSLITE_OBJ_ISNULL(obj) ((obj)->data == NULL)

nnsliteObject nnsliteObjectCopy(const nnsliteObject* src);
NNSLITE_RET nnsliteObjectInit(nnsliteObject* obj);
NNSLITE_RET nnsliteObjectFree(nnsliteObject* obj);


#endif
